/* driver.cpp
 */

#include <iostream>
#include <math.h>
#include <pthread.h>
//#include <cuda.h>
#include <cutil.h> 

#include "globals.h"
//#include "oscillators.h"
#include "synthesiser.h"
#include "rt_playback.h"
#include "string.h"

int G_argc;
char **G_argv;

// GLOBAL VARIABLES
data_bundle sync_bundle;
pthread_mutex_t rt_player_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t kill_rt_player_cond = PTHREAD_COND_INITIALIZER;
int count = 0;
double duration1 = 0;
double kernel_time = 0;
float *temp_buf;
bool kill_log=false;
//~~~~~~~~~~~~~~~~~

void *rt_player_launcher(void *shared_data_bundle);

int main(int argc, char *argv[]) {
  temp_buf = (float*)malloc(SAMPLE_SIZE*NUM_SLOTS*sizeof(float));
  std::cout << "GPU synthesis start..." << std::endl;
  
  G_argc = argc;
  G_argv = argv;
  //	float runtime = 0.0, prev_runtime = 0.0, tot_time = 0.0;
  //	int itrs = 1;
  //	float delta = 0.0;
  
  pthread_t rt_player_thread;
  memset(&sync_bundle, 0, sizeof(data_bundle));
  for (int i = 0; i < NUM_SLOTS; i++) {
	 init_DeviceMem(&(sync_bundle.buf_d_slot[i]),
				SAMPLE_SIZE * sizeof(float));
	 sync_bundle.buf_d_slot_mutex[i] = (pthread_mutex_t*) malloc(
																					 sizeof(pthread_mutex_t));
	 pthread_mutex_init(sync_bundle.buf_d_slot_mutex[i], NULL);
	 sync_bundle.buf_d_status[i] = SLOT_EMPTY;
  }
  sync_bundle.sidx=0;
  sync_bundle.notEmpty = (pthread_cond_t*) malloc(
																  sizeof(pthread_cond_t));
  sync_bundle.notFull = (pthread_cond_t*) malloc(
																 sizeof(pthread_cond_t));
  pthread_cond_init(sync_bundle.notEmpty, NULL);
  pthread_cond_init(sync_bundle.notFull, NULL);
  
  int rt_player_thread_status = pthread_create(&rt_player_thread, NULL,
															  rt_player_launcher, (void*) &sync_bundle);
  if (rt_player_thread_status) {
	 std::cout << "thread creation failed ";
  }
  
  
  
  syn_launcher(&sync_bundle, &kill_rt_player_cond);
  pthread_join(rt_player_thread, NULL);
  //  printf("\nduration: %lf", duration1/(double)(CLOCKS_PER_SEC));
  //  std::cout << "\nGPU synthesis end..." << std::endl;
  return 0;
}

void *rt_player_launcher(void *shared_data_bundle) {
  pthread_mutex_lock(&rt_player_mutex);
  
  rtPlayer *p = new rtPlayer(SAMPLE_SIZE, SAMPLE_RATE);
  p->initialize_player(&(callback), shared_data_bundle);
  p->play();
  
  // wait for kill playback signal
  pthread_cond_wait(&kill_rt_player_cond, &rt_player_mutex);
  //  std::cout << "recieved rt player kill signal\n";
  p->stop();
  // for(int i=0; i<500; i++) {
  // 	 std::cout << temp_buf[i] << "\n";
  // } std::cout << std::endl;
  pthread_mutex_unlock(&rt_player_mutex);
  return NULL;
}
